package com.urbo.android.shortcutter;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
 * @author radovan.urban@gmail.com
 *
 */
public class ActivityList extends Activity implements OnItemClickListener {
		
	// column titles used for mapping 
	public final static String ITEM_LABEL = "label";
	public final static String ITEM_CLASS_NAME = "class_name";
	public final static String ITEM_PACKAGE_NAME = "package_name";
	public final static String ITEM_IMAGE = "image";
	
	// Array of item identifiers in mapped list
	private static String[] arrayColumnNames = new String[]{ITEM_LABEL, ITEM_CLASS_NAME};//, ITEM_IMAGE};
	// Array of IDs of Views to map to 
	private static int[] arrayViewIds = new int[]{R.id.row_label, R.id.row_class_name};//, R.id.row_icon};
	// Arapter to populate mapped list to ListView
	private ImageAdapter listViewAdapter; // Adapter from List to ListView  
	// Mapped list containing items to populate
	private List<Map<String, String>> listOfItems;	
	// List of Drawables to speedup listView browsing. IconItemData contains activityName to sort this list to the same order as listOfItems 
	private List<ImageAdapter.IconItemData> listOfItemsIcons;
	
	private PackageManager packageManager; 
	private ProgressDialog busyDialog ;			// Busy dialog waiting for list of activities to be retrieved

	private ShortcutDialog shortcutDialog;

	private int selectedItemPosition;
	public Context context;

	/**
	 * map Comparator. To sort retrieved list of activities 
	 */
	class MapItemComparator implements Comparator<Map<String,String>> {
	    public int compare(Map<String,String> map1, Map<String,String> map2) {
	            return map1.get(ITEM_LABEL).toString().compareTo(map2.get(ITEM_LABEL.toString()));
	    }
	}
	
	class IconItemDataComparator implements Comparator<ImageAdapter.IconItemData> {
	    public int compare(ImageAdapter.IconItemData map1, ImageAdapter.IconItemData map2) {
	            return map1.label.compareTo(map2.label);
	    }
	}
	
	/**
	 * Handler purposed to hide busyDialog after query of packages and activities
	 */
	private Handler messageHandler = new Handler() {	
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			attachViewAdapter();
			busyDialog.dismiss();
		}
	};
	
	/**
	 * Create one item to put to listOfItems. Item contains two mebers - label and class name.
	 * Name of drawable is planned to next version
	 * @param label name of the package
	 * @param className class name of the package(activity)
	 * @return Item witch several mapped records
	 */
	public Map<String,String> createItem(String label, String className, String packageName){//, String image) {  

	    Map<String,String> item = new HashMap<String,String>();  
	    item.put(ITEM_LABEL, label);  
	    item.put(ITEM_CLASS_NAME, className);
	    item.put(ITEM_PACKAGE_NAME, packageName);
	    //item.put(ITEM_IMAGE, image);
	    return item;  
	}

	/**
	 * Query list of available Activities of given type. 
	 * 	
	 * @param action a type of activities to query. For example 'android.intent.action.MAIN'. 
	 */
	private void getListOfActivity(String action) {

		final Intent intent = new Intent(action);
		List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);
		Drawable tmpDrawable = null;
	 	   
	 	for (ResolveInfo i : list) {
	 	    	 
	 		try {
	 			tmpDrawable = (Drawable)packageManager.getApplicationIcon(i.activityInfo.packageName);
	 			String tmpLabel = i.activityInfo.loadLabel(packageManager).toString();
	 			
	 			ImageAdapter.IconItemData newItem = new ImageAdapter.IconItemData();
	 			newItem.label = tmpLabel;
	 			newItem.icon = tmpDrawable;
	 			
	 			listOfItemsIcons.add( newItem ); 
		 		listOfItems.add(this.createItem(tmpLabel, i.activityInfo.name, i.activityInfo.packageName));		
	 		} catch (Exception e) {
	 			
	 		}
	 	}
	 }
	
	/**
	 * Sort list of activities, create adapter and attach adapter to ListView 
	 */
	private void attachViewAdapter()
	{
		// Sort items
		MapItemComparator tmpComparator = new MapItemComparator();
		Collections.sort(listOfItems, tmpComparator);
		
		IconItemDataComparator tmpComparator1 = new IconItemDataComparator();
		Collections.sort(listOfItemsIcons, tmpComparator1);
		
		// Attach adapter to listView
		listViewAdapter = new ImageAdapter(getApplicationContext(), listOfItems, listOfItemsIcons, R.layout.activity_list_item, arrayColumnNames, arrayViewIds);
		ListView thisListView = (ListView)findViewById(R.id.activity_list_view);
		thisListView.setAdapter(listViewAdapter);
		thisListView.setOnItemClickListener(ActivityList.this);
	}
	
	/**
	 * After activityDialog is successfully OKed, shortcut is created 
	 */
	public DialogInterface.OnClickListener shortcutDialogClick = new DialogInterface.OnClickListener(){
		@Override
		public void onClick(DialogInterface dialog, int which) {
			
			BitmapDrawable iconFromDialog = (BitmapDrawable)shortcutDialog.getShortcutIcon();
			shortcutDialog.dismiss();
	
			// Cancel click
			if (which == -2) return;
			@SuppressWarnings("unchecked")
			Map<String, String> item = (Map<String,String>) listViewAdapter.getItem(selectedItemPosition);
			String activityClass = item.get(ITEM_CLASS_NAME);
			String packageName = item.get(ITEM_PACKAGE_NAME);
			String shortcutTitle = shortcutDialog.getShortcutTitle(); 
		 
			Shortcut.createShortcut(ActivityList.this, packageName, activityClass, shortcutTitle, iconFromDialog);
		}
	};
	
	/**
	 * Click listener for sigle item. Starts dialog for item and title change
	 */
	@Override
	public void onItemClick(AdapterView<?> arg, View view, int position,long id) {
		
		// Save selected position for later use
		selectedItemPosition = position;
		
		// Set dialog Title EditText to selected class label
		String selectedItemLabel = ((TextView) view.findViewById(R.id.row_label)).getText().toString();
		shortcutDialog.setShortcutTitle(selectedItemLabel);
		shortcutDialog.setShortcutIcon(((ImageView)view.findViewById(R.id.row_icon)).getDrawable());
		shortcutDialog.show(0);
	}
	
	/**
	 * Here is the view created 
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.activity_list);
		
		//Initialization of local members
		context = this;
		packageManager = context.getPackageManager();
		listOfItems = new LinkedList<Map<String,String>>();
		listOfItemsIcons = new LinkedList<ImageAdapter.IconItemData>();
		shortcutDialog = new ShortcutDialog(context, R.layout.activity_dialog, shortcutDialogClick);
		
		//Show busy animated dialog
		this.busyDialog = ProgressDialog.show(ActivityList.this, "", this.getResources().getString(R.string.text_retrieving), true);
		
		//Start query of activities in background thread
		new Thread() {
			public void run() {
				try {
					getListOfActivity(Intent.ACTION_MAIN);
				}
				catch(Exception e) {}
				
				messageHandler.sendEmptyMessage(0);
			}
		}.start();
	}
}


